home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
076-100
/
disk_078
/
mandelvroom
/
contour.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
32KB
|
1,116 lines
/***************************************************************************
*
* MandelVroom Contour Editing Window
*
* Kevin L. Clague
*
* Copyright (C) 1987
*
**************************************************************************/
#include "mand.h"
extern struct Screen *screen;
extern struct RastPort *rp;
extern struct Window *MandWind;
extern SHORT MouseX,MouseY;
extern SHORT MaxCount;
extern struct Menu Menu[];
extern USHORT CmdMode;
extern SHORT Zoom;
USHORT CurContour;
struct Window *ContWind;
BYTE ContTitle[80];
struct NewWindow NewCont = {
0,200-80, /* start position */
320,200, /* width, height */
(UBYTE) 0, (UBYTE) 1, /* detail pen, block pen */
/* IDCMP flags */
MENUPICK | GADGETDOWN | GADGETUP | REQCLEAR | CLOSEWINDOW,
/* MandWind flags */
WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SIMPLE_REFRESH | NOCAREREFRESH,
(struct Gadget *) NULL, /* first gadget */
(struct Image *) NULL, /* user checkmark */
(UBYTE *) NULL, /* window title */
(struct Screen *) NULL, /* pointer to screen */
(struct BitMap *) NULL, /* pointer to superbitmap */
80,80,320,200, /* sizing */
CUSTOMSCREEN /* type of screen */
};
SHORT Ceiling = 1023;
extern SHORT *CountBase;
extern SHORT CountX, CountY;
SHORT Contours[NUMCONTS] = {
1023,128,64, 32, 27, 26, 25, 24,
23, 22, 21, 20, 19, 18, 17, 16,
15, 14, 13, 12, 11, 10, 9, 8,
7, 6, 5, 4, 3, 2, 1, 0
};
SHORT *ContourBase = Contours;
SHORT NumContours = NUMCONTS;
UBYTE Colors[NUMCONTS] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31
};
UBYTE *ColorBase = Colors;
struct Gadget *ContGadget[NUMCONTS];
struct Gadget *SelGadget[NUMCONTS];
/*
* Figure out what to do for this contour gadget
*/
DoContourDown(gadget)
struct Gadget *gadget;
{
USHORT ContNum;
USHORT Type;
extern LONG NavTop, NavBot, NavLeft, NavRight;
ContNum = gadget->GadgetID & NUMMASK;
switch (Type = gadget->GadgetID >> TYPEBITS & TYPEMASK) {
case CONTCNTLS:
switch (gadget->GadgetID) {
case CONTRECOL:
ReColor();
DisplayBeep(screen);
if (Zoom) {
DrawBox(NavLeft, NavTop, NavRight, NavBot );
DrawExtras(NavLeft, NavTop, NavRight, NavBot );
}
SetNormPointer();
break;
case CONTSMTH:
SetToPointer();
CmdMode = SMOOTH;
break;
}
break;
case CONTSELS:
if (CmdMode == SMOOTH) {
SetNormPointer();
SmoothContours(CurContour, ContNum);
} else {
SetNormPointer();
CmdMode = IMPLIEDSET;
}
break;
case CONTDOWNS:
if (*(ContourBase + ContNum) > 0) {
*(ContourBase + ContNum) -= 1;
}
ReString(ContNum);
SetNormPointer();
break;
case CONTUPS:
if (*(ContourBase + ContNum) < MaxCount) {
*(ContourBase + ContNum) += 1;
}
ReString(ContNum);
SetNormPointer();
break;
}
if ( Type != CONTCNTLS ) {
DrawContBox(CurContour, 0);
DrawContBox(ContNum, 1);
CurContour = ContNum;
SetContTitle(ContNum);
}
}
/*
* Figure out what to do for this contour gadget
*/
DoContourUp(gadget)
struct Gadget *gadget;
{
USHORT ContNum;
struct PropInfo *PropInfo;
ULONG VertPot;
char msg[80];
ContNum = gadget->GadgetID & NUMMASK;
SetNormPointer();
PropInfo = (struct PropInfo *) gadget->SpecialInfo;
VertPot = PropInfo->VertPot + 1;
switch (gadget->GadgetID >> TYPEBITS & TYPEMASK) {
case CONTCNTLS:
Ceiling = ((LONG) MaxCount - ( VertPot * MaxCount >> 16));
ModAll();
break;
case CONTPOTS:
if (ContourBase[ContNum] < Ceiling) {
ContourBase[ContNum] =
( (LONG) Ceiling ) - (VertPot * Ceiling >> 16);
} else {
PropInfo->VertPot = 0;
RefreshGList(gadget,ContWind,NULL,1);
}
DrawContBox(CurContour, 0);
DrawContBox(ContNum, 1);
CurContour = ContNum;
SetContTitle(ContNum);
break;
}
}
/*
* Set the contour window's new title
*/
SetContTitle(ContNum)
int ContNum;
{
SHORT Low, High;
char *fmt1 = "Contour: %d Alt: %d-%d Pen: %d";
char *fmt2 = "Contour: %d Alt: %d Pen: %d";
High = ContourBase[ContNum];
if (ContNum != 0) {
Low = ContourBase[ContNum-1];
if (Low == High || Low - High == 1) {
sprintf(ContTitle, fmt2, ContNum, High, ColorBase[ContNum]);
} else {
sprintf(ContTitle, fmt1, ContNum, Low - 1, High, ColorBase[ContNum]);
}
} else {
sprintf(ContTitle, fmt2, ContNum, MaxCount, High, ColorBase[ContNum]);
}
SetWindowTitles(ContWind, ContTitle, NULL);
}
/*
* Set Potentiometer knob's pen
*/
DrawContBox(Contour, pen)
ULONG Contour;
int pen;
{
LONG Left, Right, Top, Bottom;
LONG Scaled4;
struct RastPort *rp = ContWind->RPort;
extern USHORT XScale, YScale;
Scaled4 = 4 << XScale;
Left = (6 << XScale) * Contour + Scaled4 - 1;
Right = Left + Scaled4 + 1;
Top = (12 << YScale) - 1;
Bottom = Top + (4 << YScale) + 1;
SetDrMd(rp, (LONG) JAM1);
SetAPen(rp, (LONG) pen);
/*
* Draw the new box
*/
Move(rp, Left, Top );
Draw(rp, Right, Top );
Draw(rp, Right, Bottom);
Draw(rp, Left, Bottom);
Draw(rp, Left, Top+1 );
} /* DrawContBox */
/*
* There was a window pick. Do what we need to do to service it
*/
DoWindowPick(MouseX,MouseY)
SHORT MouseX,MouseY;
{
USHORT Height;
if (MouseX >= LEFTMARG && MouseX <= MandWind->Width-RIGHTMARG &&
MouseY >= TOPMARG && MouseY <= MandWind->Height-BOTMARG) {
if (CmdMode == IMPLIEDSET) {
Height = *(CountBase + (MouseY-TOPMARG)*CountX + MouseX - LEFTMARG);
*(ContourBase + CurContour) = Height;
ReString(CurContour);
}
}
}
/*
* Smooth the heights over a subrange of contours
*/
SmoothContours(First,Second)
USHORT First, Second;
{
USHORT Temp;
float Diff,Start;
if (Second-First != 0) {
if (Second < First) {
Temp = First;
First = Second;
Second = Temp;
}
Start = (float) ContourBase[First];
Diff = (((float) ContourBase[Second]) - Start)/((float)(Second-First));
if (Diff > -1.0) {
Diff = -1.0;
}
for ( ; First < Second && Start > 0; First++)
ContourBase[First + 1] = (SHORT) (Start += Diff);
if (Start == 0) {
for ( ; First < NumContours; First++) {
ContourBase[First] = 0;
}
}
ModAll();
}
} /* SmoothContours */
/*
* ReColor the Mandelbrot image
*/
ReColor() {
SHORT *CountPtr = CountBase;
SHORT Mask,Width;
LONG Mod,CMod;
SHORT LF,LP,RF,RP,D[6];
SHORT i,j,k,l, Depth;
LONG Sx,TL;
SHORT *Planes[6];
UBYTE *ColorPtr;
UBYTE *ColorSave,t;
UBYTE T[1030];
Depth = screen->BitMap.Depth;
if (CountPtr == NULL) {
DispErrMsg("No counts to recolor",0);
return(0);
}
if (screen->Width < CountX+LEFTMARG+RIGHTMARG ||
screen->Height < CountY+TOPMARG+BOTMARG) {
DispErrMsg("Picture too big for screen.",0);
return(0);
}
if (MandWind->Width != CountX+LEFTMARG+RIGHTMARG ||
MandWind->Height != CountY+TOPMARG+BOTMARG)
SizeWindow(MandWind,CountX+LEFTMARG+RIGHTMARG-MandWind->Width,
CountY+TOPMARG+BOTMARG-MandWind->Height);
WindowToFront(MandWind);
SetAPen( rp, 0L );
RectFill( rp, LEFTMARG, TOPMARG, LEFTMARG + CountX, TOPMARG + CountY );
if ( Depth < 4 || Depth == 6) {
ReColorSlow();
return(0);
}
/* try to get enough memory to recolor the picture fast. */
ColorPtr = ColorSave = (UBYTE *) AllocMem((LONG) CountX * CountY, 0L);
if (ColorPtr == (UBYTE *) NULL) {
ReColorSlow();
return(0);
}
/* So recolor it now that you have the memory */
for (i = 0,j = 1029; i < NUMCONTS; i++)
for (; j >= ContourBase[i] && j; )
T[j--] = ColorBase[i];
while (j >= 0) T[j--] = 0;
;
#ifdef SLOW1
for (Sx = CountX*CountY; Sx-- >= 0; ) *(ColorPtr++) = T[*(CountPtr++)];
#else
#asm
CountPtr equ -4
ColorBase equ -82
T equ -1117
move.w _CountX,d1
muls.w _CountY,d1
sub.l #1,d1
move.l CountPtr(a5),a0
lea T(a5),a1
move.l ColorBase(a5),a6
ColorLoop
move.w (a0)+,d0
move.b (a1,d0.w),(a6)+
sub.l #1,d1
bge ColorLoop
#endasm
#endif
ClearMenuStrip(MandWind);
if (Depth == 4) {
ReColor4(ColorSave);
} else
if (Depth == 5) {
ReColor5(ColorSave);
}
SetMenuStrip(MandWind, Menu);
FreeMem(ColorSave,CountX*CountY);
} /* ReColor */
/*
* Assembly code to recolor 4 bit planes
*/
ReColor4(ColorSave)
UBYTE *ColorSave;
{
SHORT Mask,Width;
LONG Mod,CMod;
SHORT LF,LP,RF,RP;
SHORT i,j,k,l;
LONG Sx,TL;
UBYTE *ColorPtr;
struct BitMap *BitMap = MandWind->RPort->BitMap;
#asm
SaveReg reg a0-a6/d0-d7
Plane0 equ 8
Plane1 equ Plane0+4
Plane2 equ Plane0+8
Plane3 equ Plane0+12
Plane4 equ Plane0+16
Plane5 equ Plane0+20
BitMap equ -44
ColorPtr equ -40
TL equ -36
Sx equ -32
l equ -28
k equ -26
j equ -24
i equ -22
RP equ -20
RF equ -18
LP equ -16
LF equ -14
CMod equ -12
Mod equ -8
Width equ -4
Mask equ -2
ColorSave equ 8
#endasm
ColorPtr = ColorSave;
Sx = screen->Width >> 4;
LF = MandWind->LeftEdge + 17 & 0xfff0;
LP = MandWind->LeftEdge + LEFTMARG;
CMod = CountX - (LF-LP);
Mod = Sx - 1;
TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4);
Width = LF-LP;
Mask = 0xffff << Width;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; for (i = CountY; i; i--) {
Y0Loop4 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
B0Loop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt B0Loop4 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y0Loop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
RP = LP + CountX & 0xfff0;
RF = RP - 16;
CMod = CountX - (RP-LF);
Mod = Sx - ((RP-LF) >> 4);
TL++;
Width = (RP-LF) >> 4;
ColorPtr = ColorSave + LF - LP;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1) ;i = CountY;
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; for (i = CountY; i; i--) {
YLoop4 ; /* for each column */
move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
XLoop4 ; /* pack a word for each bit plane */
move.w #16,d7 ; for (k = 16; k; k--) {
BLoop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt BLoop4 ; } /* did each bit in bit plane word */
move.w d2,(a2)+ ; Save the packed data in bit planes
move.w d3,(a3)+
move.w d4,(a4)+
move.w d5,(a5)+
sub.w d1,j(a1) ; } /* did each word in a row */
tst.w j(a1)
bgt XLoop4
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt YLoop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
TL += Width;
Width = LP + CountX - RP;
CMod = CountX - Width;
Mod = Sx - 1;
Mask = 0xffff >> Width;
ColorPtr = ColorSave + RP - LP;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y2Loop4 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
B2Loop4
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
sub.w d1,d7 ; same for bit plane 5
bgt B2Loop4 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
move.w #16,d0
sub.w Width(a1),d0
asl.w d0,d2
asl.w d0,d3
asl.w d0,d4
asl.w d0,d5
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y2Loop4
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
} /* ReColor 4 bit planes */
/*
* Assembly code to recolor 5 bit planes
*/
ReColor5(ColorSave)
UBYTE *ColorSave;
{
SHORT Mask,Width;
LONG Mod,CMod;
SHORT LF,LP,RF,RP;
SHORT i,j,k,l;
LONG Sx,TL;
UBYTE *ColorPtr;
struct BitMap *BitMap = MandWind->RPort->BitMap;
ColorPtr = ColorSave;
Sx = screen->Width >> 4;
LF = MandWind->LeftEdge + 17 & 0xfff0;
LP = MandWind->LeftEdge + LEFTMARG;
CMod = CountX - (LF-LP);
Mod = Sx - 1;
TL = Sx * (MandWind->TopEdge + TOPMARG) + (LP >> 4);
Width = LF-LP;
Mask = 0xffff << Width;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y0Loop5 ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
eor.w d6,d6
B0Loop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt B0Loop5 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
and.w d0,(a6)
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
or.w d6,(a6)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y0Loop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
RP = LP + CountX & 0xfff0;
RF = RP - 16;
CMod = CountX - (RP-LF);
Mod = Sx - ((RP-LF) >> 4);
TL++;
Width = (RP-LF) >> 4;
ColorPtr = ColorSave + LF - LP;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1) ;i = CountY;
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
YLoop5 ; /* for each column */
move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
XLoop5 ; /* pack a word for each bit plane */
move.w #16,d7 ; for (k = 16; k; k--) {
BLoop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt BLoop5 ; } /* did each bit in bit plane word */
move.w d2,(a2)+ ; Save the packed data in bit planes
move.w d3,(a3)+
move.w d4,(a4)+
move.w d5,(a5)+
move.w d6,(a6)+
sub.w d1,j(a1) ; } /* did each word in a row */
tst.w j(a1)
bgt XLoop5
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt YLoop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
TL += Width;
Width = LP + CountX - RP;
CMod = CountX - Width;
Mod = Sx - 1;
Mask = 0xffff >> Width;
ColorPtr = ColorSave + RP - LP;
#asm
movem.l SaveReg,-(sp) ;Save all the gprs to the stack
move.l a5,a1 ;We need a5, so put MANX stack in a1
move.w _CountY,i(a1)
move.l BitMap(a1),a0
move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
asl.l #1,d0 ; and make it a 'word' offset
move.l Plane0(a0),a2 ;Get address of screens first bit plane
adda.l d0,a2 ; add in window top-left offset.
move.l Plane1(a0),a3 ;Same for second bit plane.
adda.l d0,a3
move.l Plane2(a0),a4 ;Same for third bit plane.
adda.l d0,a4
move.l Plane3(a0),a5 ;Same for fourth bit plane.
adda.l d0,a5
move.l Plane4(a0),a6 ;Same for fifth bit plane.
adda.l d0,a6
move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
move.l #1,d1 ;/* for each row */
; ;for (i = CountY; i; i--) {
Y2Loop5 ; ; /* for each pixel in column */
move.w Width(a1),d7 ; for (k = Width; k; k--) {
eor.w d2,d2 ; Clear all bits in the bit plane data regs.
eor.w d3,d3
eor.w d4,d4
eor.w d5,d5
eor.w d6,d6
B2Loop5
move.b (a0)+,d0 ; d0 = *(ColorPtr++);
asr.b d1,d0 ; get low order bit from d0
addx.w d2,d2 ; put it in bit plane 0 data
asr.b d1,d0 ; same for bit plane 1
addx.w d3,d3
asr.b d1,d0 ; same for bit plane 2
addx.w d4,d4
asr.b d1,d0 ; same for bit plane 3
addx.w d5,d5
asr.b d1,d0 ; same for bit plane 4
addx.w d6,d6
sub.w d1,d7 ; same for bit plane 5
bgt B2Loop5 ; } /* did each bit in bit plane word */
move.w Mask(a1),d0 ; Turn off all the new bits in planes
and.w d0,(a2)
and.w d0,(a3)
and.w d0,(a4)
and.w d0,(a5)
and.w d0,(a6)
move.w #16,d0
sub.w Width(a1),d0
asl.w d0,d2
asl.w d0,d3
asl.w d0,d4
asl.w d0,d5
asl.w d0,d6
or.w d2,(a2)+ ; Set the new bits in the bit planes
or.w d3,(a3)+
or.w d4,(a4)+
or.w d5,(a5)+
or.w d6,(a6)+
move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
add.l d0,d0
add.l d0,a2
add.l d0,a3
add.l d0,a4
add.l d0,a5
add.l d0,a6
adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
sub.w d1,i(a1) ;} /* did each row */
tst.w i(a1)
bgt Y2Loop5
movem.l (sp)+,SaveReg ;better restore the registers
#endasm
} /* ReColor 5 bit planes */
ReColorSlow() {
LONG i, j, x, y, xl, yl;
SHORT *CountPtr = CountBase;
UBYTE T[1030];
UBYTE OldColor;
UBYTE NewColor;
j = MaxCount;
for (i = 0; i < NUMCONTS && j >= 0; i++)
for (; j >= ContourBase[i] && j >=0 ; )
T[j--] = ColorBase[i];
while (j >= 0) T[j--] = 0;
OldColor = 0xff;
xl = CountX + LEFTMARG;
yl = CountY + TOPMARG;
for (y = TOPMARG; y < yl; y++) {
for (x = LEFTMARG; x < xl; x++) {
NewColor = T[ *CountPtr++ ];
if ( NewColor != OldColor) {
SetAPen( rp, NewColor );
OldColor = NewColor;
}
if (NewColor)
WritePixel(rp, x, y);
}
}
} /* ReColorSlow */
/*
* Allocate all the gadgets and things for the contour window
*/
struct Gadget *MakeContours()
{
struct Gadget *FirstGadget, *NextGadget, *OldGadget;
extern struct Gadget *MakeBool(), *MakePot();
extern struct IntuiText *MakeIntui();
USHORT i,x,y;
UBYTE c = 0;
struct PropInfo *PropInfo;
FirstGadget = OldGadget = MakePot(228, 26, 4, 32, CONTCEIL, 0);
if (OldGadget == (struct Gadget *) NULL)
goto error;
for (x = y = 0; x < 2; y += 10, x++) {
NextGadget = MakeBool(234,y+14,6,6,1,CONTCNTL+x);
if (NextGadget == (struct Gadget *) NULL)
goto error;
switch (x) {
case 0:
NextGadget->GadgetText = MakeIntui("ReColor",10,-1,3,3,JAM1);
break;
case 1:
NextGadget->GadgetText = MakeIntui("Smooth",10,-1,3,3,JAM1);
break;
}
OldGadget->NextGadget = NextGadget;
OldGadget = NextGadget;
}
for (x = y = 0; y < NumContours; x += 6, y++) {
NextGadget = MakeBool(4+x, 12,4,4,Colors[y],CONTSEL+y);
if (NextGadget == (struct Gadget *) NULL)
goto error;
OldGadget->NextGadget = NextGadget;
OldGadget = SelGadget[y] = NextGadget;
}
NextGadget->GadgetText = MakeIntui("Set",6,-2,3,3,JAM1);
for (x = y = 0; y < NumContours; x += 6, y++) {
NextGadget = MakeBool(4+x, 18, 4, 4, 3, CONTUP + y);
if (NextGadget == (struct Gadget *) NULL)
goto error;
OldGadget->NextGadget = NextGadget;
OldGadget = NextGadget;
}
NextGadget->GadgetText = MakeIntui("+",6,-2,3,3,JAM1);
/*
* Allocate the potentiometer gadgets for contour window
*/
for (x = y = 0; y < NumContours; x += 6, y++) {
NextGadget = MakePot(4+x, 24, 4, 32, CONTPOT+y, y);
if (NextGadget == (struct Gadget *) NULL)
goto error;
PropInfo = (struct PropInfo *) NextGadget->SpecialInfo;
if (ContourBase[y] < Ceiling) {
PropInfo->VertPot =
(USHORT) ((((Ceiling - (ContourBase[y] + 1))<<16)/(Ceiling)) & 0xffff);
} else
PropInfo->VertPot = 0;
OldGadget->NextGadget = NextGadget;
ContGadget[y] = NextGadget;
OldGadget = NextGadget;
}
NextGadget->GadgetText = MakeIntui("Alt.",6,12,3,3,JAM1);
/*
* Allocate the push button gadgets for decrementing contours
*/
for (x = y = 0; y < NumContours; x += 6, y++) {
NextGadget = MakeBool(4+x, 58, 4, 4, 3, CONTDOWN + y);
if (NextGadget == (struct Gadget *) NULL)
goto error;
if (y == NUMCONTS - 1) {
NextGadget->GadgetText = MakeIntui("-",6,-2,3,3,JAM1);
}
OldGadget->NextGadget = NextGadget;
OldGadget = NextGadget;
}
return( FirstGadget );
error:
FreeGadgets(FirstGadget);
return((struct Gadget *) NULL);
} /* MakeContours */
/*
* Open the Contour window
*/
OpenContWind()
{
struct Window *OpenMyWind();
struct Gadget *gadgets;
extern USHORT YScale;
if (ContWind == (struct Window *) NULL) {
gadgets = MakeContours();
if (gadgets == (struct Gadget *) NULL) {
DispErrMsg("Can't allocate contour gadget chain",0);
return(0);
}
NewCont.TopEdge = 119 << YScale;
ContWind = OpenMyWind(&NewCont, screen, gadgets, 320, 80, 320, 80);
if (ContWind == (struct Window *) NULL) {
DispErrMsg("Can't open Contour window",0);
FreeGadgets(gadgets);
return(0);
}
SetContTitle(0);
DrawContBox(CurContour);
ForceNormPointer();
} else {
WindowToFront( ContWind );
}
return(1);
} /* OpenContWind */
/*
* Close the Mand window
*/
CloseContWind()
{
if (ContWind != (struct Window *) NULL) {
CloseMyWind(ContWind,NewCont.FirstGadget);
ContWind = (struct Window *) NULL;
}
} /* ClosePalWind */
/*
* ReDisplay a given contour potentiometer gadget
*/
ReString(PotNum)
SHORT PotNum;
{
SHORT i;
USHORT VertPot;
if (ContourBase[PotNum] < Ceiling)
VertPot = (USHORT) ((((Ceiling - (ContourBase[PotNum]+1))<<16)/(Ceiling)) & 0xffff);
else
VertPot = (USHORT) 0;
NewModifyProp(ContGadget[PotNum], ContWind, NULL, FREEVERT | PROPBORDERLESS,
0L, VertPot, 0L, 0L, 1L);
} /* ReString */
/*
* ReDisplay all the contour potentiometer gadgets
*/
ModAll()
{
SHORT i;
USHORT VertPot;
struct Gadget *PropGad = (struct Gadget *) ContGadget[0];
for (i = 0; i < NUMCONTS; i++) {
if (ContourBase[i] < Ceiling) {
VertPot = (USHORT) ((((Ceiling - (ContourBase[i] + 1))<<16)/(Ceiling)) & 0xffff);
} else
VertPot = (USHORT) 0;
NewModifyProp(PropGad,ContWind,NULL,FREEVERT|PROPBORDERLESS,0L,VertPot,0L,0L,1L);
PropGad = PropGad->NextGadget;
}
} /* ModAll */